﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using System;
using Nirvana;
using UnityEngine.UI;

public class UIWindowBase : MonoBehaviour
{
    /// <summary>
    /// UI界面状态
    /// </summary>
    public enum WindowStatus
    {
        Create,
        Open,
        Close,
        OpenAnim,
        CloseAnim,
        Pause,
        Hide,
    }
    /// <summary>
    /// UI出场动画
    /// </summary>
    public enum WindowAnimType
    {
        None,
        PopOut,
        MoveTop,
        MoveDown,
        MoveLeft,
        MoveRight,
    }

    /// <summary>
    /// UI架构关键字，表明当前UI所属那个Camera下渲染。为空则使用默认第一个UI架构
    /// </summary>
    [HideInInspector]
    public string layerKey;
    [Header("UI界面所属图层")]
    public UIType m_UIType;
    [Tooltip("UI界面显示动画")]
    public WindowAnimType windowAnimType = WindowAnimType.None;
    [Tooltip("不需选择,这里作调试用")]
    public WindowStatus windowStatus;

    [Header("每个UI界面的Canvas")]
    public Canvas m_canvas;
    [Header("UI背景遮罩")]
    public GameObject m_bgMask;
    [Tooltip("除了背景遮罩节点，所有UI元素对象都要在此节点下布局")]
    [Header("UI窗口子节点")]
    public GameObject m_uiRoot;

    protected Color m_bgMaskColor;

    /// <summary>
    /// 当前UI想监听的事件列表
    /// </summary>
    protected List<Enum> m_EventNames = new List<Enum>();


    string m_UIName = null;
    public string UIName
    {
        get
        {
            if (m_UIName == null)
            {
                m_UIName = name.Replace("(Clone)", string.Empty);
            }

            return m_UIName;
        }
        set
        {
            m_UIName = value;
        }
    }
    private void Awake()
    {
        if (m_uiRoot == null) m_uiRoot = transform.Find("rootNode")?.gameObject;

        if(m_uiRoot == null) Debug.LogErrorFormat("UI Layout Error: rootNode Dont Find on {0}", this.name);

        if (m_bgMask == null) m_bgMask = transform.Find("bgMask")?.gameObject;
        if(m_bgMask != null)
        {
            var bg = m_bgMask.GetComponent<Image>();
            if(bg != null)
            {
                m_bgMaskColor = new Color(0, 0, 0, 0.8f);
                bg.color = m_bgMaskColor;
            }
        }
        else
        {
            Debug.LogErrorFormat("UI Layout Error: bgMask Dont Find on {0}", this.name);
        }

        OnAwakeUI();
    }

    protected virtual void OnAwakeUI() { }

    private void OnDestroy() 
    {
        DestroyUI();
    }
    public void DestroyUI()
    {
        RemoveEventListener();
        OnDestroyUI();
    }
    protected virtual void OnDestroyUI() { }

    #region 虚函数

    public void Init()
    {
        m_UIName = null;
        m_canvas = GetComponent<Canvas>();
        if (m_canvas != null)
        {
            m_canvas.sortingLayerID = SortingLayer.NameToID(m_UIType.ToString());
        }
        OnInit();
    }

    //当UI第一次打开时调用OnInit方法，调用时机在OnOpen之前
    protected virtual void OnInit() { }
    

    public virtual void OnOpen()
    {
    }

    public virtual void Show()
    {
        gameObject.SetActive(true);
    }

    public virtual void Hide()
    {
        gameObject.SetActive(false);
    }

    public virtual void OnClose() { }

    public virtual void OnHide() { }

    public virtual void OnShow() { }
 
    public virtual void OnClickClose()
    {
        UIManager.CloseUIWindow(this);
    }

    public virtual void OnClickNull()
    {
        OnClickClose();
    }

    public virtual void SetSort(bool isOpen,int order = 0)
    {
        if(m_canvas == null) return;

        m_canvas.overrideSorting = isOpen;
        m_canvas.sortingOrder = order;
    }

    public void SetBGAlpha(float alpha)
    {
        var bg = m_bgMask.GetComponent<Image>();
        if(bg != null)
        {
            m_bgMaskColor.a = alpha;
            bg.color = m_bgMaskColor;
        }
    }

    /// <summary>
    /// 显示动画
    /// </summary>
    public virtual IEnumerator EnterAnim(UIAnimCallBack l_animComplete, UICallBack l_callBack)
    {
        m_uiRoot.transform.localScale = Vector3.one * 0.5f;
        Sequence ts = DOTween.Sequence();
        ts.Append(m_uiRoot.transform.DOScale(Vector3.one * 1.05f, 0.2f))
        .Append(m_uiRoot.transform.DOScale(Vector3.one * 0.98f, 0.08f))
        .Append(m_uiRoot.transform.DOScale(Vector3.one, 0.1f)).SetEase(Ease.OutSine)
        .OnComplete(()=> {


        }).SetUpdate(true);
        //默认无动画
        OnShow();
        l_animComplete(this, l_callBack);
        yield break;
    }

    public virtual void OnCompleteEnterAnim() { }

    /// <summary>
    /// 暂停动画
    /// </summary>
    public virtual IEnumerator PauserAnim(UIAnimCallBack l_animComplete, UICallBack l_callBack)
    {
        //默认无动画
        l_animComplete(this, l_callBack);
        Hide();
        yield break;
    }
    public virtual void OnCompletePauserAnim() { }

    /// <summary>
    /// 关闭动画
    /// </summary>
    public virtual IEnumerator ExitAnim(UIAnimCallBack l_animComplete, UICallBack l_callBack)
    {
        Sequence ts = DOTween.Sequence();
        ts.Append(m_uiRoot.transform.DOScale(Vector3.one * 0.3f, 0.2f))
            .SetEase(Ease.InCubic)
            .OnComplete(() => {

                //默认无动画
                l_animComplete(this, l_callBack);
                m_uiRoot.transform.localScale = Vector3.one;
            }).SetUpdate(true);

        yield break;
    }

    public virtual void OnCompleteExitAnim() { }

    #endregion

    #region ui event

    /// <summary>
    /// 对当前窗口添加需要监听的事件：比如金币栏数值刷新，购买金币时刷新下金币栏UI
    /// </summary>
    public void AddEventListener(Enum l_Event)
    {
        if (!m_EventNames.Contains(l_Event))
        {
            m_EventNames.Add(l_Event);
            EventManager.AddEvent(l_Event, Refresh);
        }
    }

    public virtual void RemoveEventListener()
    {
        for (int i = 0; i < m_EventNames.Count; i++)
        {
            EventManager.RemoveEvent(m_EventNames[i], Refresh);
        }

        m_EventNames.Clear();
    }

    public void Refresh(Enum e,params object[] args)
    {
        UISystemEvent.Dispatch(this, UIEvent.OnRefresh);
        OnRefresh(e,args);
    }

    public virtual void OnRefresh(Enum e,params object[] args) { }

    #endregion


    #region UI出场方式

    public void MoveInByUp(string name, float _time = 0.3f)
    {
        RectTransform form = transform as RectTransform;
        Vector2 _moto = form.anchoredPosition;
        form.anchoredPosition = new Vector2(_moto.x, _moto.y + 1000);

        Sequence fallingSeuence = DOTween.Sequence();
        Tweener tweener = form.DOAnchorPos(_moto, _time);
        tweener.SetEase(Ease.InOutBack);
        Tweener tweener2 = form.DOAnchorPos(new Vector2(_moto.x, _moto.y - 10), 0.1f);
        tweener.SetEase(Ease.OutBack);
        Tweener tweener3 = form.DOAnchorPos(new Vector2(_moto.x, _moto.y + 10), 0.1f);
        tweener.SetEase(Ease.OutBack);
        Tweener tweener4 = form.DOAnchorPos(_moto, 0.09f);
        tweener.SetEase(Ease.Linear);
        fallingSeuence.Append(tweener).Append(tweener2).Append(tweener3).Append(tweener4);
    }

    #endregion

}
